package networkInterface;

import hci.ChatGui;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

import observerNotification.ErrorObserverNotification;

import main.ChatSystem;

import cs.remoteapp.FileMessage;
import cs.remoteapp.Message;


/**
 * Implements TCP sending of FileMessage objects
 * 
 * <p>
 * <ul>
 * <li>Project: 	ChatSystemG3</li>
 * <li>Called by: 	ChatNI</li>
 * </ul>
 * </p>
 * 
 * @author COMBES Nicolas - LECHANTRE Arnaud
 * @see Runnable
 * @see ChatNISender
 */
public class ChatNIFileSender extends ChatNISender implements Runnable {

	/**
	 * Message containning the file
	 */
	private Message message;
	/**
	 * Remote address
	 */
	private InetAddress remoteAddress;
	/**
	 * Port to send onto
	 */
	private int port;
	/**
	 * Sending socket
	 */
	private Socket sock;
	/**
	 * Concerned interface
	 */
	private ToNetwork chatNi;
	/**
	 * Unique conversation id
	 */
	private int convId;
	/**
	 * Buffer size
	 */
	private int buffSize;
	/**
	 * Data container
	 */
	private byte[] byteArray;
	
	/**
	 * Construct; params already described. buffSize is set to 5000.
	 * @param message
	 * @param remoteAddress
	 * @param port
	 */
	public ChatNIFileSender(Message message, InetAddress remoteAddress, int port, ToNetwork chatNi, int convId){
		super();
		this.message = message;
		this.remoteAddress = remoteAddress;
		this.port = port;
		this.chatNi= chatNi;
		this.convId = convId;
		this.buffSize=5000;
		this.byteArray= new byte[buffSize];
		try {
			this.sock = new Socket(remoteAddress,port);
		} catch (IOException e) {
			System.out.println("networkInterface.ChatNIFileSender: TCP Socket couldn't be created.");
		}
	}
	
	
	/**
	 * Is able to send an object using TCP protocol and will be used only to send FileMessage ones.
	 * @param message
	 * @param remoteAddress
	 * @param port
	 */
	public void sendTCP(Message message, InetAddress remoteAddress, int port){
		if (ChatSystem.debugMode)  System.out.println("networkInterface.ChatNIFileSender: Sending file to " + remoteAddress.toString() + ":" + port + ".");
		
		/*---OLD SOCKET WRITING---
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			try {
				ObjectOutputStream oos = new ObjectOutputStream(baos);
				oos.writeObject(message);
				oos.flush();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			byte[] byteMsg = baos.toByteArray();
			OutputStream out = s.getOutputStream(); 
		    DataOutputStream dos = new DataOutputStream(out);
		    dos.write(byteMsg, 0, byteMsg.length);
			this.s.close(); 
		} catch (IOException e) {
			System.out.println("Socket to " + remoteAddress.toString() + ":" + port +" couldn't be created.");
		} 
		//---END---*/
		
		
		/* Linking a new oos to the socket output stream */
		FileInputStream fos;
		BufferedInputStream bos;
		int read;
		try {
			fos = new FileInputStream(((FileMessage)message).getFile());
			bos=new BufferedInputStream(fos);
			/* Writing directly into the stream */
			while ((read=bos.read(this.byteArray))!=-1){
				this.sock.getOutputStream().write(this.byteArray,0,read);
			}
			/* Closing stream and socket */
			fos.close();
			bos.close();
			this.sock.close();
			if(ChatSystem.debugMode)System.out.println("File transfer finished");
			this.chatNi.notifyFileTransferFinished(this, this.convId);
		} catch (IOException e) {
			this.chatNi.relayError(new ErrorObserverNotification(ChatGui.strings.getString("errorCantSendFileTxt")));
		}
		
	}


	/**
	 * Calls sendTCP method
	 * @see Runnable
	 */
	@Override
	public void run() {
		sendTCP(this.message, this.remoteAddress, this.port);
	}


	/**
	 * Closes sending socket
	 */
	@Override
	public void close() {
		try {
			this.sock.close();
		} catch (IOException e) {
			this.chatNi.notifyFileEmissionAbort(this, this.convId);
		}
		
	}
	
}
